#ifndef debouncer_H
#define debouncer_H
class debouncer
{
public:
    float process(float val)
    {
#if 0 //动态窗口
        if (abs(last_read - val) > debounce_tol)
        {
            great_rep = 0;
            if (read_cnt < debounce_max)
            {
                new_tol = abs(last_read - val) > new_tol ? abs(last_read - val) : new_tol;
                read_cnt++;
                last_read = val;
            }
            else
            {
                read_cnt = 0;
                // debounce_tol = new_tol;
                this->val = val;
            }
        }
        else
#endif
        {
            float error = this->val - val;
            if ((abs(error) > debounce_tol))
            {
                if (error > 0)
                {
                    little_rep = 0;
                    if (++great_rep > debounce_rep)
                    {
                        great_rep = 0;
                        this->val = val;
                    }
                    else
                    {
                        read_cnt++;
                    }
                }
                else
                {
                    great_rep = 0;
                    if (++little_rep > debounce_rep)
                    {
                        little_rep = 0;
                        this->val = val;
                    }
                    else
                    {
                        read_cnt++;
                    }
                }
            }
            else
            {
            }
            read_cnt = 0;
            new_tol = debounce_tol;
        }

        return abs(this->val) > zero ? this->val : 0;
    }

    debouncer(uint32_t range=10000, float tol = 65, uint16_t max = 5, uint16_t rep = 5)
    {
        this->range = range;
        zero = range / 1000;
        debounce_max = max;
        debounce_tol = tol;
        debounce_rep = rep;
        new_tol = tol;
    }
    void set_tol(float val)
    {
        debounce_tol = val;
    }

private:
    uint32_t range, zero;
    uint16_t debounce_max;       /* max number of additional readings */
    float debounce_tol, new_tol; /* tolerance used for filtering */
    uint16_t debounce_rep;       /* additional consecutive good readings*/
    uint16_t read_cnt = 0, great_rep, little_rep;
    float val = 0, last_read = 0;
};
#endif